package com.zmn.oms.zmn.business.impl.work;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Maps;
import com.zmn.common.constant.GlobalConsts;
import com.zmn.common.utils.collection.CollectionUtil;
import com.zmn.common.utils.number.NumberUtil;
import com.zmn.common.utils.reflect.BeanMapper;
import com.zmn.oms.business.interfaces.messageV1.app.MessageSendAppService;
import com.zmn.oms.business.interfaces.orderstock.OrderStockBService;
import com.zmn.oms.business.interfaces.servtype.ServItemBService;
import com.zmn.oms.business.interfaces.xno.OrderXnoBindBService;
import com.zmn.oms.common.annotation.OrderWorkCasOperate;
import com.zmn.oms.common.annotation.ZsNormalOrderWorkLog;
import com.zmn.oms.common.constant.*;
import com.zmn.oms.common.exception.OmsBaseException;
import com.zmn.oms.model.dto.orderstock.ReleaseStockDTO;
import com.zmn.oms.model.dto.work.modify.CheckQuotationTypeOrderDTO;
import com.zmn.oms.model.dto.work.modify.OrderUpdateStatusDTO;
import com.zmn.oms.model.dto.work.modify.must.OrderAssignBackDTO;
import com.zmn.oms.model.dto.work.modify.must.OrderDistributeBackDTO;
import com.zmn.oms.model.dto.work.modify.must.OrderWorkGrabDTO;
import com.zmn.oms.model.dto.work.xno.XnoUnBindDTO;
import com.zmn.oms.model.entity.detail.OrderDetail;
import com.zmn.oms.model.entity.grab.NonGridGrabOrder;
import com.zmn.oms.model.entity.order.OrderExtend;
import com.zmn.oms.model.entity.work.OrderWork;
import com.zmn.oms.model.query.grab.NonGridGrabOrderQuery;
import com.zmn.oms.model.vo.work.OperatePermissionVO;
import com.zmn.oms.model.vo.work.OrderDistributeBackVO;
import com.zmn.oms.services.interfaces.changerecord.OrderChangeRecordService;
import com.zmn.oms.services.interfaces.detail.OrderDetailService;
import com.zmn.oms.services.interfaces.grab.NonGridGrabOrderService;
import com.zmn.oms.services.interfaces.order.OrderExtendService;
import com.zmn.oms.services.interfaces.orderattachment.OrderAttachmentService;
import com.zmn.oms.services.interfaces.tag.OrderTagService;
import com.zmn.oms.services.interfaces.wallquotation.WallQuotationService;
import com.zmn.oms.services.interfaces.wallservitem.WallServItemService;
import com.zmn.oms.services.interfaces.work.OrderWorkService;
import com.zmn.oms.services.interfaces.work.masterwork.MasterWorkService;
import com.zmn.oms.zmn.business.interfaces.grab.NonGridGrabOrderBService;
import com.zmn.oms.zmn.business.interfaces.work.*;
import com.zmn.oms.zmn.business.interfaces.work.customwork.ZsCustomWorkBService;
import com.zmn.oms.zmn.business.interfaces.work.customwork.ZsDistributeWorkBService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;
import java.util.Objects;

@Slf4j
@Service
public class OrderWorkDistributeBackBServiceImpl implements OrderWorkDistributeBackBService {

    @Autowired
    private OrderWorkService orderWorkService;
    @Autowired
    private ZsOrderWorkOperatePermissionBService orderWorkOperatePermissionBService;
    @Autowired
    private ZsCustomWorkBService zsCustomWorkBService;
    @Autowired
    private OrderDetailService orderDetailService;
    @Autowired
    private MessageSendAppService messageSendAppService;
    @Autowired
   private OrderExtendService orderExtendService;
    @Autowired
    private OrderAttachmentService orderAttachmentService;
    @Autowired
    private MasterWorkService masterWorkService;
    @Autowired
    private ZsOrderWorkBService zsOrderWorkBService;
    @Autowired
    private OrderXnoBindBService orderXnoBindBService;
    @Autowired
    private OrderWorkAssignBackBService orderWorkAssignBackBService;
    @Autowired
    private ZsDistributeWorkBService zsDistributeWorkBService;
    @Autowired
    private OrderWorkGrabBService orderWorkGrabBService;
    @Autowired
    private NonGridGrabOrderService nonGridGrabOrderService;
    @Autowired
    private OrderStockBService orderStockBService;
    @Autowired
    private OrderChangeRecordService orderChangeRecordService;
    @Autowired
    private ServItemBService servItemBService;
    @Autowired
    private WallQuotationService wallQuotationService;
    @Autowired
    private WallServItemService wallServItemService;
    @Autowired
    private OrderTagService orderTagService;
    @Autowired
    private NonGridGrabOrderBService nonGridGrabOrderBService;

    @Override
    public OrderDistributeBackVO getDistributeBackVO(Long orderId, Long workId) {

        OrderWork orderWork = orderWorkService.findOrderWorkByKey(orderId, workId);

        OrderDistributeBackVO distributeBackVO = new OrderDistributeBackVO();
        distributeBackVO.setOrderId(orderId);
        distributeBackVO.setWorkId(workId);
        distributeBackVO.setHasPart(!NumberUtil.isNullOrZero(orderWork.getPartAmount()));

        return distributeBackVO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @OrderWorkCasOperate(type = OrderConsts.ORDER_OP_TYPE_DISTRIBUTE_BACK)
    @ZsNormalOrderWorkLog(type = OrderLogConsts.ORDER_LOG_TYPE_DISTRIBUTE_BACK, beforeProceed = false)
    public void saveDistributeBack(OrderDistributeBackDTO distributeBackDTO) throws OmsBaseException {

        OperatePermissionVO operatePermission = orderWorkOperatePermissionBService.getOperatePermission(distributeBackDTO.getOrderId(),
                distributeBackDTO.getWorkId(),
                OrderConsts.ORDER_OP_TYPE_DISTRIBUTE_BACK,
                distributeBackDTO.getOperatorType());

        if (!operatePermission.getCanOperate()) {
            throw new OmsBaseException(operatePermission.getMsg());
        }

        OrderWork orderWork = orderWorkService.findOrderWorkByKey(distributeBackDTO.getOrderId(), distributeBackDTO.getWorkId());
        OrderDetail orderDetail = orderDetailService.findOrderDetailByKey(orderWork.getOrderId());

        // 墙面报价需要删除暂存表信息
        wallQuotationService.deleteByKey(orderWork.getWorkId());
        wallServItemService.deleteByWorkId(orderWork.getWorkId());

        // 如果工程师属于家修匠
        if (Objects.equals(orderWork.getCompanyId(), CompanyConsts.ZMN_JXJ_COMPANY_ID)) {
            Integer oldServiceItemType = orderWork.getServItemType();
            // 重新判断工单类型
            CheckQuotationTypeOrderDTO checkQuotationTypeOrderDTO = BeanMapper.map(orderWork, CheckQuotationTypeOrderDTO.class);
            checkQuotationTypeOrderDTO.setCompanyId(null);
            checkQuotationTypeOrderDTO.setMasterId(null);
            checkQuotationTypeOrderDTO.setCompatibilityFinalPrice(true);
            Integer newServiceItemType = servItemBService.getServItemType(checkQuotationTypeOrderDTO);
            // servItemType==5的修改成4，并且标识一口价（一口价订单需求兼容app走计价器3.0流程）
            if (Objects.equals(newServiceItemType, OrderConsts.SERVICE_ITEM_TYPE_FINAL_PRICE)) {
                orderWork.setServItemType(OrderConsts.SERVICE_ITEM_TYPE_QUOTATION_THREE);
                orderWork.setFinalPrice(GlobalConsts.YES);
            }else {
                orderWork.setFinalPrice(GlobalConsts.NO);
                orderWork.setServItemType(newServiceItemType);
            }
            log.info("[{}]修改计价类型，旧类型[{}]-->新类型[{}]", orderWork.getWorkId(), oldServiceItemType, newServiceItemType);
        }

        // 网格化派单撤回直接进行分单撤回。
        boolean isGrid = zsDistributeWorkBService.isGridDistribute(orderWork);
        if (isGrid){
            distributeBackDTO.setStatus(OrderStatusConsts.WORK_STATUS_CONFIRM);
            OrderAssignBackDTO dto = BeanMapper.map(distributeBackDTO, OrderAssignBackDTO.class);
            orderWorkAssignBackBService.saveGridAssignBack(orderWork, orderDetail, dto, isGrid);

            // 释放库存
            ReleaseStockDTO releaseStockDTO = new ReleaseStockDTO();
            releaseStockDTO.setOrderId(orderWork.getOrderId());
            releaseStockDTO.setWorkId(orderWork.getWorkId());
            releaseStockDTO.setMasterId(orderWork.getMasterId());
            releaseStockDTO.setCityId(orderWork.getCityId());
            orderStockBService.releaseStock(releaseStockDTO);
            return;
        }
        //1未出发  2已出发
        orderWork.setIsLeave(1);

        // 修改师傅出发状态
        masterWorkService.updateMasterLeave(orderWork);

        if (Objects.equals(orderDetail.getBindStatus(), OrderConsts.BIND_STATUS_BIND)) {
            // 解绑小号
            XnoUnBindDTO xnoUnBindDTO = new XnoUnBindDTO();
            xnoUnBindDTO.setOrderId(orderWork.getOrderId());
            xnoUnBindDTO.setWorkId(orderWork.getWorkId());
            orderXnoBindBService.unBind(xnoUnBindDTO);
        }

        OrderUpdateStatusDTO updateStatusDTO = new OrderUpdateStatusDTO();
        updateStatusDTO.setOrderId(distributeBackDTO.getOrderId());
        updateStatusDTO.setWorkId(distributeBackDTO.getWorkId());

        // 已分派状态
        updateStatusDTO.setStatus(OrderStatusConsts.WORK_STATUS_ASSIGN);
        updateStatusDTO.setOperator(distributeBackDTO.getOperator());
        updateStatusDTO.setOperatorId(distributeBackDTO.getOperatorId());
        zsCustomWorkBService.updateToAssignStatus(updateStatusDTO);

        OrderExtend orderExtendByOrderId = orderExtendService.findOrderExtendByOrderId(distributeBackDTO.getOrderId());
        // 清空个人形象照片数据
        OrderExtend orderExtend = new OrderExtend();
        orderExtend.setExtId(distributeBackDTO.getOrderId());
        orderExtend.setMasterSrc("");
        // 转派前跳过扫码重置扫码字段
        orderExtend.setOperateVisitScan(orderExtendByOrderId.getOperateVisitScan() == 1 ? 0 : orderExtendByOrderId.getOperateVisitScan());
        if (Objects.equals(orderWork.getServItemType(), OrderConsts.SERVICE_ITEM_TYPE_QUOTATION_THREE)) {
            orderExtend.setWeChatScanUserId(0L);
        }
        orderExtendService.clearDistributeInfo(orderExtend);

        // 清空渠道附件
        orderAttachmentService.deleteByOrderId(distributeBackDTO.getOrderId());

        // 派单撤回重新操作,重置报价及优惠信息
        zsOrderWorkBService.resetQuotationInfo(orderWork);

        // 发送撤回app消息
        Map<String, Object> params = Maps.newHashMap();
        params.put("order_id", String.valueOf(orderWork.getOrderId()));
        params.put("work_id", String.valueOf(orderWork.getWorkId()));
        messageSendAppService.pushAppMessageInfo(MessageConsts.ZMN_MSG_RULEID_BACK, JSON.toJSONString(params),orderWork);

        // 如果是抢单撤回，订单改为指派
        if (Objects.equals(orderWork.getGrabType(), GlobalConsts.YES)) {
            OrderWorkGrabDTO dto = new OrderWorkGrabDTO();
            dto.setGrabType(GlobalConsts.NO);
            dto.setOrderId(distributeBackDTO.getOrderId());
            dto.setWorkId(distributeBackDTO.getWorkId());
            dto.setOperator(distributeBackDTO.getOperator());
            dto.setOperatorId(distributeBackDTO.getOperatorId());
            dto.setOperatorType(distributeBackDTO.getOperatorType());
            // 判断是否无网格抢单
            NonGridGrabOrderQuery query = new NonGridGrabOrderQuery();
            query.setOrderId(dto.getOrderId());
            query.setWorkId(dto.getWorkId());
            query.setValidStatus(com.zmn.consts.GlobalConsts.YES);
            List<NonGridGrabOrder> nonGridGrabOrderList = nonGridGrabOrderService.listByQuery(query);
            if (CollectionUtil.isNullOrEmpty(nonGridGrabOrderList)) {
                orderWorkGrabBService.saveGrabType(dto);
            }
        }

        // 释放库存
        ReleaseStockDTO releaseStockDTO = new ReleaseStockDTO();
        releaseStockDTO.setOrderId(orderWork.getOrderId());
        releaseStockDTO.setWorkId(orderWork.getWorkId());
        releaseStockDTO.setMasterId(orderWork.getMasterId());
        releaseStockDTO.setCityId(orderWork.getCityId());
        orderStockBService.releaseStock(releaseStockDTO);

        // 计价器3.0订单需要清空上门信息
        if (Objects.equals(orderWork.getServItemType(), OrderConsts.SERVICE_ITEM_TYPE_QUOTATION_THREE)) {
            orderChangeRecordService.clearVisitInfo(distributeBackDTO.getOrderId(), distributeBackDTO.getWorkId());
        }

        // 派单撤回清空责任工程师
        if (!Objects.equals(OrderConsts.ORDER_TYPE_REWORK, orderWork.getType())) {
            orderChangeRecordService.clearCancelLiableAndLiableMasterRecord(orderWork.getOrderId());
        }

    }

}
